'use strict'

const sm4pass = require('sm4-password')

const PostgreModel = require('psqlorm').Model

/**
 * @typedef {object} column
 * @property {string} type - 类型
 * @property {string} refActionDelete - 外键删除后的行为，可以设置为cascade，具体参考数据库文档。
 * @property {string} refActionUpdate - 外键更新后的行为，可以设置为cascade，具体参考数据库文档。
 * @property {string} ref - 外键引用，格式 ModelName:COLUMN，示例：'users:id'
 * @property {string|number} default - 默认值。
 * @property {boolean} notNull - 不允许为null，默认为true。
 * @property {string} oldName - 原column名称，如果要重命名字段，需要oldName指定原有名字。
 * @property {boolean} typeLock - 是否锁定类型，如果为true则会锁定类型，不会更新。
 *
 * 如果指定ref，type会保持和外键引用的字段一致。
 */

//在column中编辑列字段。

let _table = {
  /**
   * @type {column}
   */
  column: {
    id : {
      type : 'varchar(12)'
    },

    /**
     * @type {column}
     */
    username: {
      type: 'varchar(30)'
    },

    /**
     * @type {column}
     */
    passwd : {
      type: 'varchar(240)'
    },

    /**
     * @type {column}
     */
    role: {
      type: 'varchar(12)',
      default: 'admin'
    },

    /**
     * @type {column}
     */
    level: {
      type: 'smallint',
      default: 1
    },

    /**
     * @type {column}
     */
    email: {
      type: 'varchar(60)',
      default: ''
    },

    create_time: {
      type : 'bigint',
      default: 0
    },

    forbid: {
      type: 'smallint',
      default: 0
    }
  },

  //索引
  index: [
    'create_time',
    'role',
    'email'
  ],

  //唯一索引
  unique: [
    'username',
  ]
}

//生成hash密码以及验证密码的扩展
const upass = new sm4pass()

class Admin extends PostgreModel {

  constructor (pqorm) {
    super(pqorm)

    this.modelPath = __dirname

    //以上代码必须存在并且写在前面。

    //主键id前缀，建议不要超过2字符，请确保前缀和生成的id长度 <= 数据库字段的最大长度。
    this.idPre = ''

    //id的长度，默认为12
    //this.idLen = 12

    //默认主键名为id，并且是字符串类型，主键id会自动生成。
    //this.primaryKey = 'id'

    //数据表真正的名称。
    this.tableName = 'admin'

    this.table = _table

    this.roleLevel = {
      'super': 9,
      'admin': 1
    }

  }

  async loginVerify(username, passwd) {
    let fields = [
      'id', 'username', 'passwd', 'level', 'role', 'forbid'
    ]

    let u = await this.where('username', username).get(fields)

    if (!u) {
      return {
        ok: false,
        errmsg: '没有此用户'
      }
    }

    if (u.forbid) {
      return {
        ok: false,
        errmsg: '此用户已被冻结'
      }
    }

    if (!upass.verify(passwd, u.passwd)) {
      return {
        ok: false,
        errmsg: '密码错误'
      }
    }

    return {
      ok: true, 
      data: {
        id: u.id,
        username: u.username,
        role: u.role,
        level: u.level
      }
    }

  }

  async create (data) {
    if (!data.role || this.roleLevel[data.role] === undefined) {
      data.role = this.roleLevel.admin
    }

    data.level = this.roleLevel[data.role]

    if (data.level === this.roleLevel.super) {
      let u = await this.where('level', this.roleLevel.super).get()
      if (u) {
        throw new Error('super用户只能有一个。')
      }
    }

    data.create_time = Date.now()

    if (!data.username) {
      data.username = 'a' + Math.random().toString(16).substring(2)
    }

    let u = await this.where('username', data.username).get()
    if (u) {
      throw new Error('用户已存在：'+data.username)
    }

    if (!data.passwd) {
      data.passwd = '1234567'
    }

    data.passwd = upass.make(data.passwd)

    return this.returning(['id', 'username']).insert(data)

  }

  async updatePasswd (id, data) {
    data.passwd = upass.make(data.passwd)
    return this.where('id', id).update(data)
  }

}

module.exports = Admin
